/*
 * Copyright (C) 2006 The Android Open Source Project
 * Copyright (C) 2012 YIXIA.COM
 * Copyright (C) 2013 Zhang Rui <bbcallen@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hunantv.mglive.widget.media;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import java.util.Locale;


public class VideoController extends android.widget.MediaController {
    private static final String TAG = VideoController.class.getSimpleName();

    private static final int SHOW_PROGRESS = 1;
    private MediaPlayerControl mPlayer;
    private Context mContext;
    private ProgressBar mProgress;
    private TextView mEndTime, mCurrentTime;
    private long mDuration;
    private boolean mDragging;
    private ImageButton mPauseButton;
    private onSeekBarTouch mSeekBarTouchListener;
    private onCountdown mCountdown;

    private AudioManager mAM;
    private static boolean isNewTimeFormat;

    public VideoController(Context context) {
        super(context);
        mContext = context;
        mAM = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
    }

    public void initControllerView(ImageButton ibtn, ProgressBar progressBar, TextView tvCurrTime, TextView tvEndTime, boolean isNewTimeFormat) {
        this.isNewTimeFormat = isNewTimeFormat;
        initControllerView(ibtn, progressBar, tvCurrTime, tvEndTime);
    }

    public void initControllerView(ImageButton ibtn, ProgressBar progressBar, TextView tvCurrTime, TextView tvEndTime) {
        mPauseButton = ibtn;
        if (mPauseButton != null) {
            mPauseButton.requestFocus();
            mPauseButton.setOnClickListener(mPauseListener);
        }
        mProgress = progressBar;
        if (mProgress != null) {
            if (mProgress instanceof SeekBar) {
                SeekBar seeker = (SeekBar) mProgress;
                seeker.setOnSeekBarChangeListener(mSeekListener);
                seeker.setThumbOffset(1);
            }
            mProgress.setMax(1000);
        }
        mEndTime = tvEndTime;
        mCurrentTime = tvCurrTime;
    }

    public void show() {
        mHandler.sendEmptyMessage(SHOW_PROGRESS);
    }

    public void hide() {
        mHandler.removeMessages(SHOW_PROGRESS);
    }


    public void start() {
        mPlayer.start();
    }

    public void pause() {
        mPlayer.pause();
    }

    public void setMediaPlayer(MediaPlayerControl player) {
        mPlayer = player;
        updatePausePlay();
    }

    private void disableUnsupportedButtons() {
        try {
            if (mPauseButton != null && !mPlayer.canPause())
                mPauseButton.setEnabled(false);
        } catch (IncompatibleClassChangeError ex) {
        }
    }

    public onSeekBarTouch getmSeekBarTouchListener() {
        return mSeekBarTouchListener;
    }

    public void setSeekBarTouchListener(onSeekBarTouch mSeekBarTouchListener) {
        this.mSeekBarTouchListener = mSeekBarTouchListener;
    }

    public interface OnShownListener {
        public void onShown();
    }

    private OnShownListener mShownListener;

    public void setOnShownListener(OnShownListener l) {
        mShownListener = l;
    }

    public interface OnHiddenListener {
        public void onHidden();
    }

    private OnHiddenListener mHiddenListener;

    public void setOnHiddenListener(OnHiddenListener l) {
        mHiddenListener = l;
    }

    public onCountdown getmCountdown() {
        return mCountdown;
    }

    public void setCountdown(onCountdown mCountdown) {
        this.mCountdown = mCountdown;
    }

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            long pos;
            switch (msg.what) {
                case SHOW_PROGRESS:
                    pos = setProgress();
                    if (!mDragging) {
                        msg = obtainMessage(SHOW_PROGRESS);
                        sendMessageDelayed(msg, 1000 - (pos % 1000));
                        updatePausePlay();
                    }
                    break;
            }
        }
    };

    private long setProgress() {
        if (mPlayer == null || mDragging)
            return 0;

        int position = mPlayer.getCurrentPosition();
        int duration = mPlayer.getDuration();
        if (mProgress != null) {
            if (duration > 0) {
                long pos = (long) (1000 * position * 1.0f / duration);
                mProgress.setProgress((int) pos);
            }
            int percent = mPlayer.getBufferPercentage();
            mProgress.setSecondaryProgress(percent * 10);
        }

        mDuration = duration;
        if (mCountdown != null) {
            mCountdown.onCountdown((long) ((mDuration - position) / 1000.0f + 0.5));
        }
        if (mEndTime != null)
            mEndTime.setText(generateTime(mDuration));
        if (mCurrentTime != null)
            mCurrentTime.setText(generateTime(position));

        return position;
    }

    private static String generateTime(long position) {
        int totalSeconds = (int) ((position / 1000.0) + 0.5);

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        String fmt = "";
        if (hours > 0) {
            fmt = isNewTimeFormat ? "%02d时%02d分%02d秒" : "%02d:%02d:%02d";
            return String.format(Locale.US, fmt, hours, minutes, seconds).toString();
        } else if (isNewTimeFormat && minutes <= 0) {
            fmt = "%02d秒";
            return String.format(Locale.US, fmt, seconds).toString();
        } else {
            fmt = isNewTimeFormat ? "%02d分%02d秒" : "%02d:%02d";
            return String.format(Locale.US, fmt, minutes, seconds).toString();
        }
    }

    private View.OnClickListener mPauseListener = new View.OnClickListener() {
        public void onClick(View v) {
            doPauseResume();
        }
    };

    private void updatePausePlay() {
        if (mPauseButton == null || mPlayer == null)
            return;
        if (mPlayer.isPlaying()) {
            mPauseButton.setSelected(true);
        } else {
            mPauseButton.setSelected(false);
        }
    }

    private void doPauseResume() {
        if (mPlayer == null) {
            return;
        }
        if (mPlayer.isPlaying())
            mPlayer.pause();
        else
            mPlayer.start();
        updatePausePlay();
    }

    private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
        public void onStartTrackingTouch(SeekBar bar) {
            if (mSeekBarTouchListener != null) {
                mSeekBarTouchListener.onTouchStart();
            }
            mDragging = true;
            mAM.setStreamMute(AudioManager.STREAM_MUSIC, true);
        }

        public void onProgressChanged(SeekBar bar, int progress,
                                      boolean fromuser) {
            if (!fromuser)
                return;

            final long newposition = (mDuration * progress) / 1000;
            String time = generateTime(newposition);
            if (mCurrentTime != null)
                mCurrentTime.setText(time);
        }

        public void onStopTrackingTouch(SeekBar bar) {
            try {
                if (mSeekBarTouchListener != null) {
                    mSeekBarTouchListener.onTouchEnd();
                }
                if (null != mPlayer) {
                    mPlayer.seekTo((mDuration * bar.getProgress()) / 1000);
                }
                mAM.setStreamMute(AudioManager.STREAM_MUSIC, false);
                mDragging = false;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    private void seekTo(long progress) {
        if (mPlayer != null) {
            mPlayer.seekTo(progress);
        }
    }

    public void setEnabled(boolean enabled) {
        if (mPauseButton != null)
            mPauseButton.setEnabled(enabled);
        if (mProgress != null)
            mProgress.setEnabled(enabled);
        disableUnsupportedButtons();
    }

    public interface MediaPlayerControl {
        void start();

        void pause();

        int getDuration();

        int getCurrentPosition();

        void seekTo(long pos);

        boolean isPlaying();

        int getBufferPercentage();

        boolean canPause();

        boolean canSeekBackward();

        boolean canSeekForward();
    }


    public interface onSeekBarTouch {
        void onTouchStart();

        void onTouchEnd();
    }

    public interface onCountdown {
        void onCountdown(long time);
    }

    public void onDestory(){
        if(mHandler != null)
        {
            mHandler.removeCallbacksAndMessages(null);
        }
        this.mCountdown = null;
    }
}
